package com.aims.server.common.util;

import com.aims.server.entity.ExtAccountForm;
import com.aims.server.entity.ExtAccountItem;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;

/**
 * 企业或集团外常用账户信息表Word文档导出工具类V2
 * 严格按照制表-优化1.txt和makebill.jpg图片格式生成docx文档
 */
public class ExtAccountWordExporterV2 {

    /**
     * 导出Word文档
     *
     * @param form 表单数据
     * @return 文档字节数组
     * @throws IOException IO异常
     */
    public static byte[] exportToWord(ExtAccountForm form) throws IOException {
        try (XWPFDocument document = new XWPFDocument();
             ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            // 1. 创建标题
            createTitle(document);

            // 2. 创建集团总部基本信息表格
            createBasicInfoTable(document, form);

            // 3. 添加空行
            document.createParagraph();

            // 4. 创建企业或集团外账号信息表格
            createAccountInfoTable(document, form);

            // 5. 添加主申请账号银行印鉴和填表日期
            createFooterInfo(document);

            // 6. 添加填表说明
            createFormExplanation(document);

            // 写入输出流
            document.write(out);
            return out.toByteArray();
        }
    }

    /**
     * 创建标题
     */
    private static void createTitle(XWPFDocument document) {
        // 主标题：中国工商银行深圳市分行
        XWPFParagraph title1 = document.createParagraph();
        title1.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run1 = title1.createRun();
        run1.setText("中国工商银行深圳市分行");
        run1.setFontFamily("宋体");
        run1.setFontSize(16);
        run1.setBold(true);

        // 副标题：企业网上银行——企业或集团外币常用账户信息表
        XWPFParagraph title2 = document.createParagraph();
        title2.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run2 = title2.createRun();
        run2.setText("企业网上银行——企业或集团外币常用账户信息表");
        run2.setFontFamily("宋体");
        run2.setFontSize(14);
        run2.setBold(false);

        // 添加空行
        document.createParagraph();
    }

    /**
     * 创建集团总部基本信息表格
     * 按照新需求：
     * - 第1行1列：集团总部基本信息
     * - 第2行2列：企业名称
     * - 第3行4列：主申请账号、开户行名称
     * - 第4行6列：法定代表人、联系人、联系电话
     */
    private static void createBasicInfoTable(XWPFDocument document, ExtAccountForm form) {
        // 创建表格：4行6列（最大列数）
        XWPFTable table = document.createTable(4, 6);
        table.setWidth("100%");
        setTableBorders(table);

        // 第1行：1列，内容"集团总部基本信息"
        XWPFTableRow row0 = table.getRow(0);
        mergeCellsHorizontally(table, 0, 0, 5); // 合并6列
        setCellText(row0.getCell(0), "集团总部基本信息", true, ParagraphAlignment.CENTER);

        // 第2行：2列，企业名称
        XWPFTableRow row1 = table.getRow(1);
        setCellText(row1.getCell(0), "企业名", true, ParagraphAlignment.CENTER);
        mergeCellsHorizontally(table, 1, 1, 5); // 合并剩余5列
        setCellText(row1.getCell(1), form.getCompanyName(), false, ParagraphAlignment.LEFT);

        // 第3行：4列，主申请账号和开户行名称
        XWPFTableRow row2 = table.getRow(2);
        setCellText(row2.getCell(0), "主申请账号", true, ParagraphAlignment.CENTER);
        mergeCellsHorizontally(table, 2, 1, 2); // 合并2列给主申请账号值
        setCellText(row2.getCell(1), form.getMainApplyingAccount(), false, ParagraphAlignment.LEFT);
        setCellText(row2.getCell(3), "开户行名称", true, ParagraphAlignment.CENTER);
        mergeCellsHorizontally(table, 2, 4, 5); // 合并2列给开户行名称值
        setCellText(row2.getCell(4), form.getMainApplyingAccountBankName(), false, ParagraphAlignment.LEFT);

        // 第4行：6列，法定代表人、联系人、联系电话
        XWPFTableRow row3 = table.getRow(3);
        setCellText(row3.getCell(0), "法定代表人(或负责人)", true, ParagraphAlignment.CENTER);
        setCellText(row3.getCell(1), form.getLegalRepresentative(), false, ParagraphAlignment.LEFT);
        setCellText(row3.getCell(2), "联系人", true, ParagraphAlignment.CENTER);
        setCellText(row3.getCell(3), form.getContactPerson(), false, ParagraphAlignment.LEFT);
        setCellText(row3.getCell(4), "联系电话", true, ParagraphAlignment.CENTER);
        setCellText(row3.getCell(5), form.getContactPhone(), false, ParagraphAlignment.LEFT);
    }

    /**
     * 创建企业或集团外账号信息表格
     * 按照新需求：
     * - 4列结构
     * - 表头第2、3列合并
     * - 每个账号占5行
     * - 证书ID数量<=5则生成5行，>5则按实际数量生成
     */
    private static void createAccountInfoTable(XWPFDocument document, ExtAccountForm form) {
        List<ExtAccountItem> items = form.getItems();
        if (items == null || items.isEmpty()) {
            items = new ArrayList<>();
        }

        // 计算总行数：表头1行 + 每个账号的行数
        int totalDataRows = 0;
        List<AccountItemRowData> allRowData = new ArrayList<>();

        for (ExtAccountItem item : items) {
            // 解析证书ID
            List<String> certIds = parseCertIds(item.getBasePermissionCertIdName());
            // 每个账号至少5行，如果证书ID超过5个，则按实际数量
            int rowsPerItem = Math.max(5, certIds.size());
            totalDataRows += rowsPerItem;

            // 准备该账号的行数据
            AccountItemRowData rowData = new AccountItemRowData();
            rowData.item = item;
            rowData.certIds = certIds;
            rowData.rowCount = rowsPerItem;
            allRowData.add(rowData);
        }

        // 创建表格：表头1行 + 数据行
        int totalRows = 1 + totalDataRows;
        XWPFTable table = document.createTable(totalRows, 4);
        table.setWidth("100%");
        setTableBorders(table);

        // 创建表头：业务类型 | 企业或集团外账号信息（第2、3列合并） | 基本权限证书ID名称
        XWPFTableRow headerRow = table.getRow(0);
        setCellText(headerRow.getCell(0), "业务类型", true, ParagraphAlignment.CENTER);
        mergeCellsHorizontally(table, 0, 1, 2); // 合并第2、3列
        setCellText(headerRow.getCell(1), "企业或集团外账号信息", true, ParagraphAlignment.CENTER);
        setCellText(headerRow.getCell(3), "基本权限证书ID 名称", true, ParagraphAlignment.CENTER);

        // 填充数据行
        int currentRow = 1;
        for (AccountItemRowData rowData : allRowData) {
            ExtAccountItem item = rowData.item;
            List<String> certIds = rowData.certIds;
            int rowCount = rowData.rowCount;

            // 第1列（业务类型）：合并rowCount行
            mergeCellsVertically(table, currentRow, currentRow + rowCount - 1, 0);

            // 设置业务类型内容（新增和注销都勾选）
            String operationType = "新增☑\n注销☑";
            setCellText(table.getRow(currentRow).getCell(0), operationType, false, ParagraphAlignment.CENTER);

            // 填充5行账号信息
            String[][] fieldData = {
                {"户名", item.getAccountName()},
                {"账号", item.getAccountNo()},
                {"开户行名称", item.getOpeningBankName()},
                {"开户行号", item.getOpeningBankCode()},
                {"开户行所在地", item.getOpeningBankLocation()}
            };

            for (int i = 0; i < rowCount; i++) {
                XWPFTableRow dataRow = table.getRow(currentRow + i);

                // 第2列：字段名（只在前5行显示）
                if (i < fieldData.length) {
                    setCellText(dataRow.getCell(1), fieldData[i][0], true, ParagraphAlignment.CENTER);
                } else {
                    setCellText(dataRow.getCell(1), "", false, ParagraphAlignment.CENTER);
                }

                // 第3列：字段值（只在前5行显示）
                if (i < fieldData.length) {
                    setCellText(dataRow.getCell(2), fieldData[i][1], false, ParagraphAlignment.LEFT);
                } else {
                    setCellText(dataRow.getCell(2), "", false, ParagraphAlignment.LEFT);
                }

                // 第4列：证书ID（每行一个，如果有的话）
                if (i < certIds.size()) {
                    setCellText(dataRow.getCell(3), certIds.get(i), false, ParagraphAlignment.LEFT);
                } else {
                    setCellText(dataRow.getCell(3), "", false, ParagraphAlignment.LEFT);
                }
            }

            currentRow += rowCount;
        }
    }

    /**
     * 解析证书ID列表
     */
    private static List<String> parseCertIds(String certIdNames) {
        List<String> result = new ArrayList<>();
        if (certIdNames == null || certIdNames.trim().isEmpty()) {
            return result;
        }

        // 按逗号、中文逗号或换行符分割
        String[] parts = certIdNames.split("[,，\n]");
        for (String part : parts) {
            String trimmed = part.trim();
            if (!trimmed.isEmpty()) {
                result.add(trimmed);
            }
        }
        return result;
    }

    /**
     * 创建页脚信息
     */
    private static void createFooterInfo(XWPFDocument document) {
        XWPFParagraph para = document.createParagraph();
        XWPFRun run = para.createRun();
        run.setText("主申请账号银行行印鉴:                    填表日期:      年    月    日");
        run.setFontFamily("宋体");
        run.setFontSize(10);
    }

    /**
     * 创建填表说明
     */
    private static void createFormExplanation(XWPFDocument document) {
        XWPFParagraph para1 = document.createParagraph();
        XWPFRun run1 = para1.createRun();
        run1.setText("填表说明:");
        run1.setFontFamily("宋体");
        run1.setFontSize(10);
        run1.setBold(true);

        XWPFParagraph para2 = document.createParagraph();
        XWPFRun run2 = para2.createRun();
        String explanation = "1. 企业或集团外账户是指企业经常发生资金往来的其他企业或业的账户，" +
                "填写此表可以您在向这些企业或业订购时不必再填写对方账号、户名等资料。" +
                "企业或集团外币账户可以是开立在其他商业银行的账户。" +
                "在本表中所填写的企业或集团外账户在执行企业网上银行各项只能时为只能户使用。";
        run2.setText(explanation);
        run2.setFontFamily("宋体");
        run2.setFontSize(9);
    }

    /**
     * 设置单元格文本
     */
    private static void setCellText(XWPFTableCell cell, String text, boolean bold, ParagraphAlignment alignment) {
        cell.removeParagraph(0);
        XWPFParagraph para = cell.addParagraph();
        para.setAlignment(alignment);
        para.setVerticalAlignment(TextAlignment.CENTER);

        XWPFRun run = para.createRun();
        run.setText(text);
        run.setFontFamily("宋体");
        run.setFontSize(10);
        run.setBold(bold);

        // 设置单元格垂直居中
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    }

    /**
     * 设置表格边框
     */
    private static void setTableBorders(XWPFTable table) {
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        if (tblPr == null) {
            tblPr = table.getCTTbl().addNewTblPr();
        }

        CTTblBorders borders = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders();

        // 设置所有边框
        CTBorder border = CTBorder.Factory.newInstance();
        border.setVal(STBorder.SINGLE);
        border.setSz(BigInteger.valueOf(4));
        border.setSpace(BigInteger.ZERO);
        border.setColor("000000");

        borders.setTop(border);
        borders.setBottom(border);
        borders.setLeft(border);
        borders.setRight(border);
        borders.setInsideH(border);
        borders.setInsideV(border);
    }

    /**
     * 水平合并单元格
     */
    private static void mergeCellsHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
        for (int colIndex = fromCol; colIndex <= toCol; colIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(colIndex);
            CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();

            if (colIndex == fromCol) {
                // 第一个单元格设置为restart
                tcPr.addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // 其他单元格设置为continue
                tcPr.addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * 垂直合并单元格
     */
    private static void mergeCellsVertically(XWPFTable table, int fromRow, int toRow, int col) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();

            if (rowIndex == fromRow) {
                // 第一个单元格设置为restart
                tcPr.addNewVMerge().setVal(STMerge.RESTART);
            } else {
                // 其他单元格设置为continue
                tcPr.addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * 账号明细行数据内部类
     */
    private static class AccountItemRowData {
        ExtAccountItem item;
        List<String> certIds;
        int rowCount;
    }
}